home *** CD-ROM | disk | FTP | other *** search
/ Mac Easy 2010 May / Mac Life Ubuntu.iso / casper / filesystem.squashfs / usr / share / python-support / python-rdflib / rdflib / BNode.py < prev    next >
Encoding:
Python Source  |  2007-04-04  |  2.5 KB  |  87 lines

  1. # TODO: where can we move _unique_id and _serial_number_generator?
  2. from string import ascii_letters
  3. from random import choice
  4.  
  5. try:
  6.     from hashlib import md5
  7. except ImportError:
  8.     from md5 import md5    
  9.  
  10. def _unique_id():
  11.     """Create a (hopefully) unique prefix"""
  12.     id = ""
  13.     for i in xrange(0,8):
  14.         id += choice(ascii_letters)
  15.     return id
  16.  
  17. def _serial_number_generator():
  18.     i = 0
  19.     while 1:
  20.         yield i
  21.         i = i + 1
  22.  
  23. from rdflib.Identifier import Identifier
  24. from rdflib.syntax.xml_names import is_ncname
  25. import threading
  26.  
  27. bNodeLock = threading.RLock()
  28.  
  29. class BNode(Identifier):
  30.     """
  31.     Blank Node: http://www.w3.org/TR/rdf-concepts/#section-blank-nodes
  32.  
  33.     "In non-persistent O-O software construction, support for object
  34.     identity is almost accidental: in the simplest implementation,
  35.     each object resides at a certain address, and a reference to the
  36.     object uses that address, which serves as immutable object
  37.     identity.
  38.  
  39.     ...
  40.  
  41.     Maintaining object identity in shared databases raises problems:
  42.     every client that needs to create objects must obtain a unique
  43.     identity for them; " -- Bertand Meyer
  44.     """
  45.     __slots__ = ()
  46.  
  47.     def __new__(cls, value=None, # only store implementations should pass in a value
  48.                 _sn_gen=_serial_number_generator(), _prefix=_unique_id()):
  49.         if value==None:
  50.             # so that BNode values do not
  51.             # collide with ones created with a different instance of this module
  52.             # at some other time.
  53.             bNodeLock.acquire()
  54.             node_id = _sn_gen.next()
  55.             bNodeLock.release()
  56.             value = "%s%s" % (_prefix, node_id)
  57.         else:
  58.             # TODO: check that value falls within acceptable bnode value range
  59.             # for RDF/XML needs to be something that can be serialzed as a nodeID
  60.             # for N3 ??
  61.             # Unless we require these constraints be enforced elsewhere?
  62.             pass #assert is_ncname(unicode(value)), "BNode identifiers must be valid NCNames"
  63.  
  64.         return Identifier.__new__(cls, value)
  65.  
  66.     def n3(self):
  67.         return "_:%s" % self
  68.  
  69.     def __getnewargs__(self):
  70.         return (unicode(self), )
  71.  
  72.     def __reduce__(self):
  73.         return (BNode, (unicode(self),))
  74.  
  75.  
  76.     def __str__(self):
  77.         return self.encode("unicode-escape")
  78.  
  79.     def __repr__(self):
  80.         return """rdflib.BNode('%s')""" % str(self)
  81.  
  82.     def md5_term_hash(self):
  83.         d = md5(str(self))
  84.         d.update("B")
  85.         return d.hexdigest()
  86.  
  87.